import re
from django.contrib.auth import authenticate, login, logout as out
from django.contrib.auth.models import User
from django.shortcuts import render, redirect
from django.views import View


# Create your views here.
# 类视图 定义两个不同的方法处理不同的请求方式
# 类视图以请求方式为类方法 在对应的方式下编写对应的逻辑代码
# 自定义的类为普通类 继承 View 成为类视图
from user.forms import UserLForm


class UserView(View):
    def get(self, request):
        # get方法处理地址的get请求
        form = UserLForm()
        if 'register' in request.path:
            return render(request, 'user/register.html', context={'form': form})
        else:
            return render(request, 'user/login.html')

    def post(self, request):
        # 创建表单对象 需要绑定用户表单填写的数据 让表单对象帮我们完成校验
        form = UserLForm(request.POST)
        # is_valid()校验数据
        if form.is_valid():
            # 获取通过校验后的数据
            username = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password')
            password2 = form.cleaned_data.get('password2')
            email = form.cleaned_data.get('mailbox')
            try:
                user = User(username=username)
                user.set_password(password)
                user.save()
                # 注册成功后重定向到登录页面
                return redirect('user:login')
            except Exception as e:
                print(e)
                message = '注册失败'

        return render(request, 'user/register.html', context={'message': message})


class LoginView(View, ):
    def get(self, request):
        # get请求的时候获取页面数据 需要把表单返回给到模版进行渲染
        # 创建表单对象
        form = UserLForm()
        # 把表单对象传输给到模版 前端进行渲染的操作
        return render(request, 'user/login.html', context={'form': form})

    def post(self, request, res=None):
        # 创建表单对象 需要绑定用户表单填写的数据 让表单对象帮我们完成校验
        form = UserLForm(request.POST)
        # is_valid()校验数据
        if form.is_valid():
            # 获取通过校验后的数据
            username = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password')
            password2 = form.cleaned_data.get('password2')
            email = form.cleaned_data.get('mailbox')
            """
            user@example.com
            test.email@domain.co.uk
            user123@test-domain.org
            my_email@sub.domain.com
            """
            # 用户认证 authenticate() 如果正确的话 会返回一个用户对象 否则会返回 None
            user = authenticate(username=username, password=password, password2=password2, email=email)
            # 用户是否存在
            if user:
                # 登录成功 把登录的用户信息放到请求对象中
                # 生成新的或者更新用户会话（session）
                # 登录的用户信息放到请求对象中 绑定 request.user 后续的请求 get post 通过 request 来获取登录的用户信息
                # 处理会话的安全设置 超时的时间
                # 必须要先通过 authenticate 认证后才能调用 logout
                # 校验通过 把登录的用户信息放到请求对象中 使用内置的 login 来完成用户信息的认证
                login(request, user)
                # 使用内置的 login 来完成用户信息的认证 GET 请求方式 get通过键获取值
                next_url = request.GET.get('next')
                # 判断 next_url 是否存在 发布页的地址路由保存到 next 参数里面
                if next_url:
                    # 获取地址栏中的 next 参数保存的地址值
                    return redirect(next_url)
                else:
                    # 登录成功后重定向到首页
                    return redirect('index')
            else:
                message = '用户名或密码错误'

        return render(request, 'user/login.html', context={'message': message})


# 退出当前登录账号 跳转到登录页面重新登录新的账号
def logout(request, **kwargs):
    # 退出登录
    # request.session.flush()
    # 调用auth系统的 logout 方法来退出登录 把请求对象中登录用户信息给清除掉
    # 必须要先通过 authenticate 认证后才能调用 logout
    out(request)
    return redirect('login')
